package com.atguigu.gmall.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;

@Controller
@RequestMapping("/api/payment/alipay")
public class AlipayController {

    @Autowired
    private AlipayService alipayService;
    @Autowired
    private PaymentService paymentService;

    @RequestMapping("submit/{orderId}")
    @ResponseBody
    public String submitOrder(@PathVariable Long orderId){
        String pay = alipayService.createaliPay(orderId);
        return pay;
    }

    /**
     * 支付宝回调
     * @return
     */
    @RequestMapping("callback/return")
    public String callBack() {
        // 同步回调给用户展示信息
        return "redirect:" + AlipayConfig.return_order_url;
    }
    /**
     * 支付宝异步回调  必须使用内网穿透
     * @param paramMap
     * @return
     */
    @PostMapping("callback/notify")
    @ResponseBody
    public String alipayNotify(@RequestParam Map<String, String> paramMap) {
        boolean signVerified = false; //调用SDK验证签名
        try {
            //调用SDK验证签名
            signVerified = AlipaySignature.rsaCheckV1(paramMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        String outTradeNo = paramMap.get("out_trade_no");
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (paymentInfo == null){
            return "failure";
        }
        BigDecimal amount = paymentInfo.getTotalAmount();
        if (amount == null){
            return "failure";
        }

        String tradeStatus = paramMap.get("trade_status");

        if (signVerified){
            // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，
            //  校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){
                // 正常的支付成功，我们应该更新交易记录状态
                paymentService.paySuccess(outTradeNo,PaymentType.ALIPAY.name(), paramMap);
                return "success";
            }else {
                // TODO 验签失败则记录异常日志，并在response中返回failure.
                return "failure";
            }
        }else {
            return "failure";
        }
    }

    //  退款数据：
    //  我们需要传递订单Id order_info.id  |  order_info.out_trade_no
    //  http://localhost:8205/api/payment/alipay/refund/223
    @GetMapping("refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable Long orderId){
//  调用服务层
        Boolean flag = alipayService.refund(orderId);
        return Result.ok(flag);
    }

    //http://localhost:8205/api/payment/alipay/closePay/25
    // 根据订单Id关闭支付交易的url
    @GetMapping("closePay/{orderId}")
    @ResponseBody
    public Boolean closePay(@PathVariable Long orderId) {
        Boolean closePay = alipayService.closePay(orderId);
        return closePay;
    }
    //http://localhost:8205/api/payment/alipay/checkPayment/
    // 查看是否有交易记录,根据订单查询是否支付成功！查询支付交易记录
    @RequestMapping("checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable Long orderId){
        // 调用退款接口
        boolean flag = alipayService.checkPayment(orderId);
        return flag;
    }

    /**
     * 整合关闭过期订单
     * @param outTradeNo
     * @return
     */
    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo){
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (null!=paymentInfo){
            return paymentInfo;
        }
        return null;
    }

}
